package cn.dapeng.retry.t02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class RetryInvocationHandler<T> implements InvocationHandler {

    private int times = 0;

    private int delaySeconds = 0;
    private final T target;

    public RetryInvocationHandler(T target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Retry retry = method.getAnnotation(Retry.class);

        if(times >= retry.executeTime()) {
            return null;
        }

        long executeSeconds = System.currentTimeMillis() / 1000 + delaySeconds;

        for (;;) {
            while (System.currentTimeMillis() / 1000 >= executeSeconds) {
                try {
                    method.invoke(target, args);
                } catch (Exception e) {
                    if(retry.exception().equals(e.getCause().getClass())) {

                        if (times == retry.executeTime() - 1) {
                            e.printStackTrace();
                        }

                        times ++;
                        delaySeconds = delaySeconds + 5;
                        return invoke(proxy, method, args);
                    }

                }

            }
        }

    }

}
